package com.stefanini.pe.bbva.bp.in.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
import javax.servlet.http.HttpSession;

import org.jfree.data.general.DefaultPieDataset;
import org.primefaces.model.StreamedContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.pe.bbva.utils.Constantes;
import com.stefanini.pe.bbva.bp.in.bo.iface.ClienteBOIface;
import com.stefanini.pe.bbva.bp.in.model.ListasReporteModel;
import com.stefanini.pe.bbva.bp.in.security.AuthorizationService;
import com.stefanini.pe.bbva.bp.in.to.Cliente;
import com.stefanini.pe.bbva.bp.in.utils.ConstantesWeb;
import com.stefanini.pe.bbva.bp.in.utils.SpringApplicationContext;
import com.stefanini.pe.bbva.bp.in.utils.Util;

@Controller(value = "datoClienteController")
@RequestScoped
public class DatosClienteController extends GenericoController{
	@Autowired
	private ClienteBOIface clienteBO;
	@Autowired
	private ListasReporteModel listaReporteModel;
		
	private List listaPosicionContrato;
	private List listaDatosPerfilInversion;

	private HashMap datosAdicionales;
	private HashMap totalPosicionContrato;

	private Cliente oCliente;
	private boolean mostrarGrafico;
	
	private Date fechaDesde;
	private Date fechaHasta;

	private StreamedContent chart;
	
	public void onPageLoad(ComponentSystemEvent event) {
		try {
			AuthorizationService auth = (AuthorizationService)SpringApplicationContext.getBean("authorizationService");
			if (auth.isSessionClientAndContextValide() && !FacesContext.getCurrentInstance().isPostback()) {
				System.out.println("DatosClienteController... is not Postback");
				
				FacesContext ctx = FacesContext.getCurrentInstance();
				oCliente = (Cliente)((HttpSession) ctx.getExternalContext().getSession(false)).
													getAttribute(Constantes.OBJETO_CLIENTE_SESSION);			
				
				getSessionMap().put(ConstantesWeb.Reportes.PARAM_NOMBRE_REPORTE,ConstantesWeb.Reportes.REPORTE_DATOS_GENERAL_CLIENTE);
				
				initAll();
				cargarPosicionActual();
				cargarDatosAdicionales();
				cargarDatosPerfilInversion();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void initAll(){
		listaPosicionContrato = new ArrayList();
		listaDatosPerfilInversion = new ArrayList();
		chart = null;
		datosAdicionales = null;
		totalPosicionContrato = null;
	}

	private void cargarPosicionActual() {
		try{
			listaPosicionContrato = new ArrayList();
			
			List productos = clienteBO.listarPosicionActual(oCliente);
						
			this.setTotalPosicionContrato(new HashMap());
			this.getTotalPosicionContrato().put("descripcion", "TOTAL");
			float saldoactual = 0;
			float saldoretenido = 0;
			float saldodisponible = 0;
			float utilidadperdida = 0;
			float peso = 0;
			BigDecimal saldoActualB=new BigDecimal(0);
			BigDecimal saldoretenidoB=new BigDecimal(0);
			BigDecimal saldodisponibleB=new BigDecimal(0);
			BigDecimal utilidadperdidaB=new BigDecimal(0);
			BigDecimal pesoB=new BigDecimal(0);
			
			for(int index=0; index < productos.size(); index++){
				HashMap obj = (HashMap)productos.get(index);		
				obj.put("descripcion","TOTAL " + obj.get("descripcion"));
				if(obj.get("saldoactual") != null){
					saldoactual += Double.parseDouble(obj.get("saldoactual").toString());
					obj.put("saldoactualFormat", Util.formatDouble(new Double(obj.get("saldoactual").toString())));
					saldoActualB = saldoActualB.add(new BigDecimal(obj.get("saldoactual").toString()));
				}
				if(obj.get("saldoretenido") != null){
					saldoretenido += Double.parseDouble(obj.get("saldoretenido").toString());
					obj.put("saldoretenidoFormat", Util.formatDouble(new Double(obj.get("saldoretenido").toString())));
					saldoretenidoB = saldoretenidoB.add(new BigDecimal(obj.get("saldoretenido").toString()));
				}
				if(obj.get("saldodisponible") != null){
					saldodisponible += Double.parseDouble(obj.get("saldodisponible").toString());
					obj.put("saldodisponibleFormat", Util.formatDouble(new Double(obj.get("saldodisponible").toString())));
					saldodisponibleB = saldodisponibleB.add(new BigDecimal(obj.get("saldodisponible").toString()));
				}
				if(obj.get("utilidadperdida") != null){
					utilidadperdida += Double.parseDouble(obj.get("utilidadperdida").toString());
					obj.put("utilidadperdidaFormat", Util.formatDouble(new Double(obj.get("utilidadperdida").toString())));
					utilidadperdidaB = utilidadperdidaB.add(new BigDecimal(obj.get("utilidadperdida").toString()));
				}
				if(obj.get("peso") != null){
					peso += Double.parseDouble(obj.get("peso").toString());
					obj.put("pesoFormat", Util.formatDoublePorcentaje(new Double(obj.get("peso").toString())));
					obj.put("ptotalFormat", Util.formatDoublePorcentaje(new Double(obj.get("peso").toString()))+"%");
					pesoB = pesoB.add(new BigDecimal(obj.get("peso").toString()));
				}
			}
			
			this.getTotalPosicionContrato().put("saldoactual",Util.formatDouble(saldoActualB.doubleValue()));//new Double(saldoactual)
			this.getTotalPosicionContrato().put("saldoretenido", Util.formatDouble(saldoretenidoB.doubleValue()));//new Double(saldoretenido)
			this.getTotalPosicionContrato().put("saldodisponible", Util.formatDouble(saldodisponibleB.doubleValue()));//new Double(saldodisponible)
			this.getTotalPosicionContrato().put("utilidadperdida", Util.formatDouble(utilidadperdidaB.doubleValue()));//new Double(utilidadperdida)
			
			this.getTotalPosicionContrato().put("peso", "100%"); //new Double(peso)
				
			this.setListaPosicionContrato(productos);
			graficoProductos();

			HashMap obj=new HashMap();
			obj.put("listaPosicionContrato", this.getListaPosicionContrato());
			obj.put("sumaPosicionContrato", this.getTotalPosicionContrato());
			listaReporteModel.setListaReporteDatosGeneralesCliente(new ArrayList());
			listaReporteModel.getListaReporteDatosGeneralesCliente().add(obj);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public void graficoProductos() {
		DefaultPieDataset pieSource = new DefaultPieDataset();		
		try {
			for (int i = 0; i < this.getListaPosicionContrato().size() - 1; i++) {	
				HashMap map = (HashMap) this.getListaPosicionContrato().get(i);
				pieSource.setValue(map.get("descripcion").toString()+":"+Double.parseDouble(map.get("peso").toString()) +"%", 
								   Double.parseDouble(map.get("peso").toString()));	
			}
			this.setChart(Util.getPieChart(pieSource));
			this.listaReporteModel.setChart(Util.getPieChartFile(pieSource));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void cargarDatosPerfilInversion() {
		try{
			listaDatosPerfilInversion = clienteBO.listarDatosPerfilInversion(oCliente);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private void cargarDatosAdicionales() {
		try{
			this.datosAdicionales=new HashMap();
			this.datosAdicionales=(HashMap)(clienteBO.listarDatosAdicionales(oCliente).get(0));
			if(datosAdicionales.get("fecnacimiento") != null) {
				datosAdicionales.put("fecnacimiento", Util.formatoFecha(datosAdicionales.get("fecnacimiento").toString()));
			}
			FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("datosAdicionales", datosAdicionales);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public List getListaPosicionContrato() {
		return listaPosicionContrato;
	}

	public void setListaPosicionContrato(List listaPosicionContrato) {
		this.listaPosicionContrato = listaPosicionContrato;
	}

	public List getListaDatosPerfilInversion() {
		return listaDatosPerfilInversion;
	}

	public void setListaDatosPerfilInversion(List listaDatosPerfilInversion) {
		this.listaDatosPerfilInversion = listaDatosPerfilInversion;
	}

	public HashMap getDatosAdicionales() {
		return datosAdicionales;
	}

	public void setDatosAdicionales(HashMap datosAdicionales) {
		this.datosAdicionales = datosAdicionales;
	}

	public boolean isMostrarGrafico() {
		return mostrarGrafico;
	}

	public void setMostrarGrafico(boolean mostrarGrafico) {
		this.mostrarGrafico = mostrarGrafico;
	}

	public HashMap getTotalPosicionContrato() {
		return totalPosicionContrato;
	}

	public void setTotalPosicionContrato(HashMap totalPosicionContrato) {
		this.totalPosicionContrato = totalPosicionContrato;
	}
	
	public List formateaListaElementos(List listaElement){
		List listaFormato=new ArrayList();
		for(int index=0; index < listaElement.size(); index++) {
			HashMap obj = (HashMap)listaElement.get(index);
			
			if(obj.get("saldoactual") != null)
				obj.put("saldoactual",Util.formatDouble(Double.parseDouble(obj.get("saldoactual").toString())));
			if(obj.get("saldoretenido") != null)
				obj.put("saldoretenido",Util.formatDouble(Double.parseDouble(obj.get("saldoretenido").toString())));
			if(obj.get("saldodisponible") != null)
				obj.put("saldodisponible",Util.formatDouble(Double.parseDouble(obj.get("saldodisponible").toString())));
			if(obj.get("utilidadperdida") != null)
				obj.put("utilidadperdida",Util.formatDouble(Double.parseDouble(obj.get("utilidadperdida").toString())));
			if(obj.get("peso") != null)
				obj.put("peso",Util.formatDouble(Double.parseDouble(obj.get("peso").toString())));
			
			listaFormato.add(obj);	
		}
		
		return listaFormato;
	}
	
	public HashMap formateaElementos(HashMap element){
		
		HashMap obj = element;
		
		if(obj.get("saldoactual") != null)
			obj.put("saldoactual",Util.formatDouble(Double.parseDouble(obj.get("saldoactual").toString())));
		if(obj.get("saldoretenido") != null)
			obj.put("saldoretenido",Util.formatDouble(Double.parseDouble(obj.get("saldoretenido").toString())));
		if(obj.get("saldodisponible") != null)
			obj.put("saldodisponible",Util.formatDouble(Double.parseDouble(obj.get("saldodisponible").toString())));
		if(obj.get("utilidadperdida") != null)
			obj.put("utilidadperdida",Util.formatDouble(Double.parseDouble(obj.get("utilidadperdida").toString())));
		if(obj.get("peso") != null)
			obj.put("peso",Util.formatDouble(Double.parseDouble(obj.get("peso").toString())));
			
		return obj;
	}
	
	public StreamedContent getChart() {
		return chart;
	}

	public void setChart(StreamedContent chart) {
		this.chart = chart;
	}

	public Date getFechaDesde() {
		return fechaDesde;
	}

	public void setFechaDesde(Date fechaDesde) {
		this.fechaDesde = fechaDesde;
	}

	public Date getFechaHasta() {
		return fechaHasta;
	}

	public void setFechaHasta(Date fechaHasta) {
		this.fechaHasta = fechaHasta;
	}
}
